/*
 * @Author: cpu_code
 * @Date: 2020-05-05 21:01:30
 * @LastEditTime: 2020-05-06 09:31:18
 * @FilePath: \linux_network\UNIX_net\lib\readline.c
 * @Gitee: https://gitee.com/cpu_code
 * @CSDN: https://blog.csdn.net/qq_44226094
 */
/* include readline */
#include	"unp.h"


ssize_t readline(int fd, void *vptr, size_t maxlen);
static ssize_t my_read(int fd, char *ptr);
ssize_t Readline(int fd, void *ptr, size_t maxlen);
ssize_t readlinebuf(void **vptrptr);

static int	read_cnt;
static char	*read_ptr;
static char	read_buf[MAXLINE];

static ssize_t my_read(int fd, char *ptr)
{
    if(read_cnt <= 0)
    {
again:
        if((read_cnt = read(fd, read_buf, sizeof(read_buf))) < 0)
        {
            if(errno == EINTR)
            {
                goto again;
            }
            return(-1);
        }
        else if(read_cnt == 0)
        {
            return (0);
        }
        retd_ptr = read_buf;
    }

    read_cnt--;
    *ptr = *read_ptr++;
    return (1);
}

ssize_t readline(int fd, void *vptr, size_t maxlen)
{
    ssize_t	n, rc;
    char	c, *ptr;

    ptr = vptr;

    for(n = 1; n < maxlen; n++)
    {
        if((rc = my_read(fd, &c)) == 1)
        {
            *ptr++ = c;
            if(c == '\n')
            {
                break;	/* newline is stored, like fgets() */
            }
        }
        else if (rc == 0)
        {
            *ptr = 0;
            return(n - 1);	/* EOF, n - 1 bytes were read */
        }
        else
        {
            return(-1);		/* error, errno set by read() */
        }
    }
    *ptr = 0;	/* null terminate like fgets() */
	return(n);
}

/**
 * @function: 查看内部缓冲区的状态
 * @parameter: 
 * @return: 
 * @note: 
 */
ssize_t readlinebuf(void **vptrptr)
{
	if (read_cnt)
    {
		*vptrptr = read_ptr;
    }
	return(read_cnt);
}

ssize_t Readline(int fd, void *ptr, size_t maxlen)
{
	ssize_t	n;

	if( (n = readline(fd, ptr, maxlen)) < 0)
    {
		err_sys("readline error");
    }

	return(n);
}